package com.deprecated.patch;

import java.awt.Color;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JTextField;

import com.panopset.compat.Strings;
import com.panopset.UpdateListener;
import com.panopset.sf.App;
import com.panopset.sf.FontManager;
import com.panopset.sf.FontManager.FontType;

/**
 * Validating Text Field. Background red if invalid, yellow if blank.
 *
 * @author Karl Dinwiddie
 *
 */
public abstract class ValidatingField<T> {

    /**
     * Name of field.
     */
    private final String name;

    /**
     *
     * @param name
     *            Name of field, used in alerts when not valid.
     */
    public ValidatingField(final String name) {
        this.name = name;

       // FontManager.register(tf, FontType.monospace);

        tf.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(final KeyEvent e) {
                if (KeyEvent.VK_ENTER == e.getKeyCode()
                        && nextInput != null) {
                    ValidatingField.this.updateGui();
                    nextInput.requestFocus();
                }
            }
            @Override
            public void keyReleased(final KeyEvent e) {
                ValidatingField.this.updateGui();
            }
        });

        tf.addFocusListener(new FocusAdapter() {

            @Override
            public void focusLost(final FocusEvent e) {
                ValidatingField.this.save();
            }
        });
        updateGui();
    }

    public final String getName() {
        return name;
    }

    /**
     * @return Text value.
     */
    public abstract T getValue() throws Exception;

    /**
     * Set value.
     *
     * @param val
     *            Value to set.
     */
    public void setValue(final String val) {
        tf.setText(val);
        tf.invalidate();
        updateGui();
        //App.app.f.getFrame().validate();
    }

    private JTextField nextInput;
    
    public void setNextInput(final JTextField nextInput) {
        this.nextInput = nextInput;
    }
    
    /**
     * Text field.
     */
    private final TTextField tf = new TTextField() {

        @Override
        public void setEnabled(final boolean enabled) {
            super.setEnabled(enabled);
            updateGui();
        }
    };

    /**
     * @return TTextField.
     */
    public final TTextField getTf() {
        return tf;
    }

    /**
     * Validate field.
     *
     * @param s
     *            Value to validate.
     * @return true iff valid.
     */
    public abstract boolean validate(final String s);

    /**
     * Focus lost, save value somewhere.
     */
    public abstract void save();

    /**
     * Update.
     */
    public String updateGui() {
        String s = tf.getText();
        if (!tf.isEnabled()) {
            tf.setBackground(Color.WHITE);
            return s;
        }
        if (Strings.isPopulated(s)) {
            if (validate(s)) {
                tf.setBackground(Color.WHITE);
            } else {
                tf.setBackground(Color.RED);
            }
        } else {
            tf.setBackground(Color.YELLOW);
        }
        for (UpdateListener ul : uls) {
            ul.update();
        }
        return s;
    }
    
    public void addUpdateListener(final UpdateListener updateListener) {
        uls.add(updateListener);
    }

    
    private final List<UpdateListener> uls = new ArrayList<UpdateListener>();
}
